package io.renren.service.impl;

import io.renren.common.exception.RRException;
import io.renren.common.utils.ConfigConstant;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.DecimalUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.ProjectConstant;
import io.renren.common.utils.Query;
import io.renren.common.validator.Assert;
import io.renren.controller.WebSocketRoom;
import io.renren.dao.SendPacketDao;
import io.renren.entity.BalanceDetailEntity;
import io.renren.entity.MemberEntity;
import io.renren.entity.RoomEntity;
import io.renren.entity.SendPacketEntity;
import io.renren.service.BalanceDetailService;
import io.renren.service.CenterService;
import io.renren.service.MemberService;
import io.renren.service.RoomService;
import io.renren.service.SendPacketService;
import io.renren.service.SysConfigService;
import io.renren.service.TeamService;

import java.util.Date;
import java.util.Map;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

@Service("sendPacketService")
public class SendPacketServiceImpl extends ServiceImpl<SendPacketDao, SendPacketEntity> implements SendPacketService {

	@Autowired
	MemberService memberService;

	@Autowired
	RoomService roomService;

	@Autowired
	CenterService centerService;

	@Autowired
	SysConfigService sysConfigService;

	@Autowired
	BalanceDetailService balanceDetailService;

	@Autowired
	TeamService teamService;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		Long roomId = (Long) params.get("roomId");
		Page<SendPacketEntity> page = this.selectPage(new Query<SendPacketEntity>(params).getPage(), new EntityWrapper<SendPacketEntity>().eq(roomId != null, "room_id", roomId).ge("create_time", DateTime.now().minusMinutes(30).toDate()).orderBy("create_time", false));

		return new PageUtils(page);
	}

	@Override
	public PageUtils myPacketPage(Map<String, Object> params) {
		Long memberId = (Long) params.get("memberId");
		Page<SendPacketEntity> page = new Query<SendPacketEntity>(params).getPage();
		page = page.setRecords(baseMapper.myPacketPage(page, memberId));
		return new PageUtils(page);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public SendPacketEntity send(MemberEntity member, Long roomId, Double amount, Integer landmine, Integer packetQty) {
		Assert.notNull(member, "会员不存在");
		Assert.isTrue(member.getUserLevel() == ProjectConstant.USER_LEVEL_ROBOT || amount <= member.getBalance(), "您的金币不足,请先充值");
		Assert.isTrue(member.getUserLevel() == ProjectConstant.USER_LEVEL_ROBOT || roomId.equals(member.getRoomId()), "您不在此房间");

		RoomEntity room = roomService.selectById(roomId);
		Assert.notNull(room, "房间不存在");
		Assert.isTrue(room.getStatus() == ProjectConstant.COMMON_YES, "房间被禁止");
		double landReturnRate = checkPacketQty(room.getPacketQty(), packetQty);// 检查发包数量是否有效

		Date now = new Date();

		Assert.isTrue(room.getMinAmount() <= amount && amount <= room.getMaxAmount() && amount % room.getMinAmount() == 0, "金币必须是" + room.getMinAmount() + "的倍数且不超过" + room.getMaxAmount());
		// 判断是否为VIP房间
		if (room.getIsVip() == ProjectConstant.COMMON_YES) {
			Assert.isTrue(now.before(room.getVipExpireTime()), "VIP房间已过期");
		}

		// 插入发包数据
		SendPacketEntity sendPacketEntity = new SendPacketEntity();
		sendPacketEntity.setRoomId(roomId);
		sendPacketEntity.setMemberId(member.getId());
		sendPacketEntity.setFee(DecimalUtils.mul(amount, sysConfigService.getValueD(ConfigConstant.TRANS_FEE)));
		sendPacketEntity.setAmount(amount);
		sendPacketEntity.setGrabAmount(0D);
		sendPacketEntity.setBalanceAmount(DecimalUtils.sub(amount, sendPacketEntity.getFee()));
		sendPacketEntity.setGrabQty(0);
		sendPacketEntity.setLandmine(landmine);
		sendPacketEntity.setStatus(ProjectConstant.PACKET_STATUS_INITIAL);
		sendPacketEntity.setIsRobot(member.getUserLevel() == ProjectConstant.USER_LEVEL_ROBOT ? ProjectConstant.COMMON_YES : ProjectConstant.COMMON_NO);
		sendPacketEntity.setCreateTime(now);
		sendPacketEntity.setPacketQty(packetQty);
		sendPacketEntity.setBalanceQty(packetQty);
		sendPacketEntity.setLandReturnRate(landReturnRate);
		this.insert(sendPacketEntity);

		// 扣去用户余额
		member.setBalance(DecimalUtils.sub(member.getBalance(), amount));
		member.setUpdateTime(now);
		// 控制可提现金额
		if (member.getUserLevel() != ProjectConstant.USER_LEVEL_ROBOT && member.getWithdrawAmountLimit() > 0) {
			member.setWithdrawAmountLimit(DecimalUtils.sub(member.getWithdrawAmountLimit(), amount));
			if (member.getWithdrawAmountLimit() < 0) {
				member.setWithdrawAmountLimit(0D);
			}
		}
		// 机器人不更余额
		if (sendPacketEntity.getIsRobot() == ProjectConstant.COMMON_NO) {
			Assert.isTrue(memberService.updateById(member), "系统繁忙,请重试");
		}

		// 计算推荐人佣金
		teamService.commission(member.getId(), amount);
		// 房间返佣金
		if (room.getIsVip() == ProjectConstant.COMMON_YES && room.getVipMemberId() != null) {
			teamService.commissionRoom(room.getVipMemberId(), amount);
		}

		// 记录历史
		if (sendPacketEntity.getIsRobot() == ProjectConstant.COMMON_NO) {
			BalanceDetailEntity detail = new BalanceDetailEntity();
			detail.setMemberId(member.getId());
			detail.setBalanceChange(DecimalUtils.sub(0, amount));
			detail.setType(ProjectConstant.ORDER_TYPE_SEND_PACKET);
			detail.setDescription("发红包");
			detail.setCreateTime(now);
			detail.setPacketId(sendPacketEntity.getId());
			balanceDetailService.insert(detail);
		}

		// 下面参数供前端判断使用
		sendPacketEntity.setNickname(member.getNickname());
		sendPacketEntity.setHeadImg(member.getHeadImg());
		sendPacketEntity.setMyGrabAmount(0D);
		sendPacketEntity.setCountDown((DateUtils.addDateMinutes(sendPacketEntity.getCreateTime(), sysConfigService.getValueI(ConfigConstant.PACKET_EXPIRE)).getTime() - System.currentTimeMillis()) / 1000);

		WebSocketRoom.broadcastRP(sendPacketEntity, "send");// 通知房间会员

		return sendPacketEntity;
	}

	/**
	 * 检查发包数量并返回中雷赔率
	 * 
	 * @param packetQty
	 * @param qty
	 * @return
	 */
	private double checkPacketQty(String packetQty, int qty) {
		try {
			String[] arrays = packetQty.split(",");
			for (String qrStr : arrays) {
				String[] qr = qrStr.split("@");
				if (Integer.parseInt(qr[0]) == qty) {
					return Double.parseDouble(qr[1]);
				}
			}
		} catch (Exception e) {
		}
		throw new RRException("发包数量无效");
	}
}
